package cn.samler.shopapi.Service.impl;

import cn.samler.shopapi.Entity.Address;
import cn.samler.shopapi.Entity.Order;
import cn.samler.shopapi.Entity.SpecItem;
import cn.samler.shopapi.Entity.User;
import cn.samler.shopapi.Mapper.OrderMapper;
import cn.samler.shopapi.Model.Request.Order.Cart;
import cn.samler.shopapi.Model.Request.Order.CreateByCart;
import cn.samler.shopapi.Model.Request.Order.Goods;
import cn.samler.shopapi.Model.Request.Order.Payment;
import cn.samler.shopapi.Model.Response.Goods.GoodsBrief;
import cn.samler.shopapi.Model.Response.Goods.GoodsDetails;
import cn.samler.shopapi.Model.Response.Goods.Spec;
import cn.samler.shopapi.Model.Response.Order.OrderBrief;
import cn.samler.shopapi.Model.Response.Order.OrderDetails;
import cn.samler.shopapi.Model.Sys.ServiceResult;
import cn.samler.shopapi.Service.AddressService;
import cn.samler.shopapi.Service.CartService;
import cn.samler.shopapi.Service.GoodsService;
import cn.samler.shopapi.Service.OrderService;
import cn.samler.shopapi.Utils.OrderNoGenerator;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    private final OrderMapper orderMapper;
    private final GoodsService goodsService;
    private final CartService cartService;
    private final AddressService addressService;

    OrderServiceImpl(OrderMapper orderMapper, GoodsService goodsService, CartService cartService, AddressService addressService) {
        this.orderMapper = orderMapper;
        this.goodsService = goodsService;
        this.cartService = cartService;
        this.addressService = addressService;
    }

    @Override
    public OrderDetails findById(User user, String id) {
        Order order = orderMapper.findById(user.getId(), id);
        if (order != null) {
            Address address = addressService.getAddressById(user, order.getAid());

            OrderDetails orderDetails = new OrderDetails();
            orderDetails.setId(order.getTradeNo());
            orderDetails.setPayType(order.getPayType());

            List<Cart> cartList = JSON.parseArray(JSON.toJSONString(order.getGoodsList()), Cart.class);
            List<GoodsDetails> orderDetailsGoodsList = new ArrayList<>();
            cartList.forEach(cart -> {
                GoodsDetails goodsDetails = goodsService.getGoodsById(cart.getGid());
                List<Spec> goodsDetailsSpec = new ArrayList<>();
                cart.getSpec().forEach((specId, itemId) -> {
                    Spec spec = new Spec();
                    cn.samler.shopapi.Entity.Spec sItem = goodsService.getSpecById(cart.getGid(), Integer.parseInt(specId));
                    spec.setId(sItem.getId());
                    spec.setName(sItem.getName());
                    spec.setItem(new ArrayList<SpecItem>() {
                        {
                            this.add(goodsService.getSpecItemById(sItem.getId(), itemId));
                        }
                    });
                    goodsDetailsSpec.add(spec);
                });

                goodsDetails.setSpec(goodsDetailsSpec);
                orderDetailsGoodsList.add(goodsDetails);
            });
            orderDetails.setGoodsList(orderDetailsGoodsList);
            orderDetails.setAddress(address);
            orderDetails.setMoney(order.getMoney());
            orderDetails.setRemark(order.getRemark());
            orderDetails.setDate(order.getDate());
            orderDetails.setStatus(order.getStatus());

            return orderDetails;
        }

        return null;
    }

    @Override
    public List<OrderBrief> listOrder(User user, Integer type, int page, int offset) {
        List<Order> orderList = null;
        if (type == null) orderList = orderMapper.listOrder(user.getId(), (page - 1) * offset, offset);
        else orderList = orderMapper.listOrderByStatus(user.getId(), type, (page - 1) * offset, offset);

        if (orderList == null || orderList.size() == 0)
            return null;

        List<OrderBrief> orderBriefList = new ArrayList<>();
        orderList.forEach(order -> {
            OrderBrief orderBrief = new OrderBrief();
            orderBrief.setId(order.getTradeNo());

            List<Integer> goodsList = new ArrayList<>();
            // 这里还有一点问题 不使用此方法进行转换的话 会出现LinkedHashMap cannot be cast to ... 的错误
            List<Cart> cartList = JSON.parseArray(JSON.toJSONString(order.getGoodsList()), Cart.class);
            cartList.forEach(spec -> goodsList.add(spec.getGid()));
            List<GoodsBrief> goodsBriefList = goodsService.getGoodsBriefByIdList(goodsList);

            for (int i = 0; i < cartList.size() && i < goodsBriefList.size(); i++) {
                if (cartList.get(i).getGid() == goodsBriefList.get(i).getId()) {
                    GoodsBrief tmp = goodsBriefList.get(i);
                    tmp.setNumber(cartList.get(i).getNumber());

                    goodsBriefList.set(i, tmp);
                }
            }

            orderBrief.setGoodsList(goodsBriefList);
            orderBrief.setMoney(order.getMoney());
            orderBrief.setDate(order.getDate());
            orderBrief.setStatus(order.getStatus());
            orderBrief.setRemark(order.getRemark());

            orderBriefList.add(orderBrief);
        });


        return orderBriefList;
    }

    @Override
    public boolean confirmOrder(User user, String id) {
        return orderMapper.confirmOrder(user.getId(), id);
    }

    @Override
    public ServiceResult createByCart(User user, CreateByCart carts) {
        if (addressService.getAddressById(user, carts.getAid()) == null)
            return ServiceResult.failure("地址不存在");

        String orderNo;
        do {
            orderNo = OrderNoGenerator.getInstance().create();
        } while (orderMapper.findId(orderNo) > 0);

        Order order = new Order();
        order.setTradeNo(orderNo);
        order.setUid(user.getId());

        List<Cart> goodsList = new ArrayList<>();
        AtomicReference<Double> money = new AtomicReference<>(0d);
        carts.getCart().forEach(item -> {
            cn.samler.shopapi.Entity.Goods goodsItem = goodsService.getGoodsById(item.getGid());
            cn.samler.shopapi.Entity.Cart cartObj = cartService.findByToken(user.getId(), item.getGid(), item.getSpecToken());

            if (goodsItem != null && cartObj != null) {
                Cart cart = new Cart();
                cart.setGid(item.getGid());
                cart.setNumber(cartObj.getNumber());
                cart.setSpec(cartObj.getSpec());

                goodsList.add(cart);

                money.updateAndGet(v -> v + goodsItem.getPrice() * cartObj.getNumber());
            }
        });
        order.setGoodsList(goodsList);
        order.setAid(carts.getAid());
        order.setMoney(money.get());
        order.setRemark(carts.getRemark());
        order.setDate(new Date());


        if (orderMapper.create(order)) {
            carts.getCart().forEach(item -> {
                System.out.println("remove:" + item);
                cartService.removeByToken(user.getId(), item.getGid(), item.getSpecToken());
            });

            return ServiceResult.success(orderNo);
        }

        return ServiceResult.failure(null);
    }

    @Override
    public ServiceResult createByGoods(User user, Goods goods) {
        if (addressService.getAddressById(user, goods.getAid()) == null)
            return ServiceResult.failure("地址不存在");

        if (goods.getNumber() > 0) {
            cn.samler.shopapi.Entity.Goods item = goodsService.getGoodsById(goods.getGid());
            if (item != null) {
                String orderNo;
                do {
                    orderNo = OrderNoGenerator.getInstance().create();
                } while (orderMapper.findId(orderNo) > 0);

                Order order = new Order();
                order.setTradeNo(orderNo);
                order.setUid(user.getId());

                order.setGoodsList(
                        new ArrayList<cn.samler.shopapi.Model.Request.Order.Cart>() {
                            {
                                cn.samler.shopapi.Model.Request.Order.Cart cart = new cn.samler.shopapi.Model.Request.Order.Cart();
                                cart.setGid(goods.getGid());
                                cart.setNumber(goods.getNumber());
                                cart.setSpec(goods.getSpec());
                                this.add(cart);
                            }
                        }
                );
                order.setAid(goods.getAid());
                order.setMoney(goods.getNumber() * item.getPrice());
                order.setRemark(goods.getRemark());
                order.setDate(new Date());


                if (orderMapper.create(order))
                    return ServiceResult.success(orderNo);

                return ServiceResult.failure("订单创建失败");
            }

            return ServiceResult.failure("商品不存在");
        }

        return ServiceResult.failure("提交数据有误");
    }

    @Override
    public boolean payment(User user, Payment payment) {
        return orderMapper.payment(user.getId(), payment.getId(), payment.getPayType());
    }
}
